package cn.huaguo.trigger.http;

import cn.huaguo.domain.task.model.entity.TaskEntity;
import cn.huaguo.domain.task.model.valobj.TaskPageQueryVO;
import cn.huaguo.domain.task.model.valobj.TaskStatusVO;
import cn.huaguo.domain.task.model.valobj.TaskTypeVO;
import cn.huaguo.domain.task.service.ITaskService;
import cn.huaguo.trigger.http.dto.TaskAddReqDTO;
import cn.huaguo.trigger.http.dto.TaskPageQueryReqDTO;
import cn.huaguo.trigger.http.dto.TaskRushReqDTO;
import cn.huaguo.trigger.http.dto.TaskUpdateReqDTO;
import cn.huaguo.types.common.Constants;
import cn.huaguo.types.context.BaseContext;
import cn.huaguo.types.enums.ResponseCode;
import cn.huaguo.types.model.PageResult;
import cn.huaguo.types.model.Response;
import com.alibaba.fastjson.JSON;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.RandomStringUtils;
import org.springframework.dao.InvalidDataAccessApiUsageException;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;

/**
 * @Description 任务控制器
 * @Author wangQian
 * @Date 2024/5/14
 */
@Slf4j
@RestController
@RequestMapping("/task")
public class TaskController {
    @Resource
    private ITaskService taskService;

    /**
     * 新增任务
     *
     * @param taskAddReqDTO
     * @return
     */
    @PostMapping("/addTask")
    public Response addTask(@RequestBody TaskAddReqDTO taskAddReqDTO) {
        try {
            log.info("新增任务: {}", JSON.toJSONString(taskAddReqDTO));
            // 参数校验
            if (!TaskTypeVO.COMMON_INFO.getCode().equals(taskAddReqDTO.getTaskType()) &&
                    !TaskTypeVO.PLATFORM_TRADE.getCode().equals(taskAddReqDTO.getTaskType())) {
                throw new IllegalArgumentException("任务类型错误，请检查");
            }
            if (TaskTypeVO.PLATFORM_TRADE.getCode().equals(taskAddReqDTO.getTaskType())) {
                taskService.publishTradeTask(TaskEntity.builder()
                        .taskId(RandomStringUtils.randomNumeric(16))
                        .taskContent(taskAddReqDTO.getTaskContent())
                        .taskReward(taskAddReqDTO.getTaskReward())
                        .taskPhone(taskAddReqDTO.getTaskPhone())
                        .deadline(taskAddReqDTO.getDeadline())
                        .taskAddress(taskAddReqDTO.getTaskAddress())
                        .taskType(TaskTypeVO.PLATFORM_TRADE.getCode())
                        .build());
            } else {
                taskService.publishNoTradeTask(TaskEntity.builder()
                        .taskId(RandomStringUtils.randomNumeric(16))
                        .taskContent(taskAddReqDTO.getTaskContent())
                        .taskReward(taskAddReqDTO.getTaskReward())
                        .taskPhone(taskAddReqDTO.getTaskPhone())
                        .deadline(taskAddReqDTO.getDeadline())
                        .taskAddress(taskAddReqDTO.getTaskAddress())
                        .taskType(TaskTypeVO.COMMON_INFO.getCode())
                        .build());
            }

            log.info("新增任务成功：{}", JSON.toJSONString(taskAddReqDTO));
            return Response.builder()
                    .code(ResponseCode.SUCCESS.getCode())
                    .info(ResponseCode.SUCCESS.getInfo())
                    .build();
        } catch (Exception e) {
            log.error("新增任务失败：{} message: {}", JSON.toJSONString(taskAddReqDTO), e.getMessage());
            return Response.builder()
                    .code(ResponseCode.UN_ERROR.getCode())
                    .info(StringUtils.hasLength(e.getMessage()) ? e.getMessage() : ResponseCode.UN_ERROR.getInfo())
                    .build();
        }
    }

    /**
     * 支付回调
     *  TODO 支付回调
     *
     * @return
     */
    @PostMapping()
    public Response payCallback() {
        return Response.builder().build();
    }

    /**
     * 分页条件查询任务列表
     *
     * @param taskPageQueryReqDTO
     * @return
     */
    @GetMapping("/taskList")

    public Response<PageResult<TaskEntity>> taskList(@RequestBody TaskPageQueryReqDTO taskPageQueryReqDTO) {
        try {
            log.info("条件查询任务列表: {}", JSON.toJSONString(taskPageQueryReqDTO));
            PageResult<TaskEntity> pageResult =
                    taskService.queryTaskList(TaskPageQueryVO.builder()
                            .pageNum(taskPageQueryReqDTO.getPageNum())
                            .pageSize(taskPageQueryReqDTO.getPageSize())
                            .campusName(taskPageQueryReqDTO.getCampusName())
                            .searchKey(taskPageQueryReqDTO.getSearchKey())
                            .taskType(taskPageQueryReqDTO.getTaskType())
                            .build(), null);
            log.info("查询任务列表成功: {}", JSON.toJSONString(pageResult));
            // 封装结果返回
            return Response.<PageResult<TaskEntity>>builder()
                    .code(ResponseCode.SUCCESS.getCode())
                    .info(ResponseCode.SUCCESS.getInfo())
                    .data(pageResult)
                    .build();
        } catch (Exception e) {
            log.error("查询任务列表失败: {} message: {}", JSON.toJSONString(taskPageQueryReqDTO), e.getMessage());
            return Response.<PageResult<TaskEntity>>builder()
                    .code(ResponseCode.UN_ERROR.getCode())
                    .info(StringUtils.hasLength(e.getMessage()) ? e.getMessage() : ResponseCode.UN_ERROR.getInfo())
                    .build();
        }
    }

    /**
     * 分页查询当前用户任务列表
     *
     * @param taskPageQueryReqDTO
     * @return
     */
    @GetMapping("/myTaskList")
    public Response<PageResult<TaskEntity>> myTaskList(@RequestBody TaskPageQueryReqDTO taskPageQueryReqDTO) {
        try {
            log.info("分页查询当前用户任务列表");
            PageResult<TaskEntity> pageResult =
                    taskService.queryTaskList(TaskPageQueryVO.builder()
                            .pageNum(taskPageQueryReqDTO.getPageNum())
                            .pageSize(taskPageQueryReqDTO.getPageSize())
                            .build(), BaseContext.getCurrentId());
            log.info("分页查询当前用户任务列表: {} currentId :{}", JSON.toJSONString(pageResult), BaseContext.getCurrentId());
            // 封装结果返回
            return Response.<PageResult<TaskEntity>>builder()
                    .code(ResponseCode.SUCCESS.getCode())
                    .info(ResponseCode.SUCCESS.getInfo())
                    .data(pageResult)
                    .build();
        } catch (Exception e) {
            log.error("分页查询当前用户任务列表失败: {} message: {}", BaseContext.getCurrentId(), e.getMessage());
            return Response.<PageResult<TaskEntity>>builder()
                    .code(ResponseCode.UN_ERROR.getCode())
                    .info(StringUtils.hasLength(e.getMessage()) ? e.getMessage() : ResponseCode.UN_ERROR.getInfo())
                    .data(null)
                    .build();
        }
    }


    /**
     * 根据任务id查询任务详情
     *
     * @param taskId
     * @return
     */
    @GetMapping("/taskInfo/{taskId}")
    public Response<TaskEntity> taskInfo(@PathVariable String taskId) {
        try {
            log.info("查询任务详情: taskId={}", taskId);
            TaskEntity taskEntity = taskService.getTaskById(taskId);
            log.info("查询任务详情成功: {}", JSON.toJSONString(taskEntity));

            // 封装结果返回
            return Response.<TaskEntity>builder()
                    .code(ResponseCode.SUCCESS.getCode())
                    .info(ResponseCode.SUCCESS.getInfo())
                    .data(taskEntity)
                    .build();
        } catch (Exception e) {
            log.error("查询任务详情失败: taskId={} message: {}", taskId, e.getMessage());
            return Response.<TaskEntity>builder()
                    .code(ResponseCode.UN_ERROR.getCode())
                    .info(ResponseCode.UN_ERROR.getInfo())
                    .data(null)
                    .build();
        }
    }

    /**
     * 更新任务信息
     *
     * @param taskUpdateReqDTO
     * @return
     */
    @PutMapping("/update")
    public Response<Boolean> updateTask(@RequestBody TaskUpdateReqDTO taskUpdateReqDTO) {
        try {
            log.info("更新任务: {}", JSON.toJSONString(taskUpdateReqDTO));
            Boolean result = taskService.updateTask(TaskEntity.builder()
                    .taskId(taskUpdateReqDTO.getTaskId())
                    .taskContent(taskUpdateReqDTO.getTaskContent())
                    .taskReward(taskUpdateReqDTO.getTaskReward())
                    .taskPhone(taskUpdateReqDTO.getTaskPhone())
                    .deadline(taskUpdateReqDTO.getDeadline())
                    .taskAddress(taskUpdateReqDTO.getTaskAddress())
                    .build());
            log.info("更新任务成功: {}", JSON.toJSONString(taskUpdateReqDTO));
            Response<Boolean> response = Response.<Boolean>builder()
                    .code(ResponseCode.SUCCESS.getCode())
                    .info(ResponseCode.SUCCESS.getInfo())
                    .data(result)
                    .build();
            return response;
        } catch (Exception e) {
            log.error("更新任务失败: {} message: {}", JSON.toJSONString(taskUpdateReqDTO), e.getMessage());
            return Response.<Boolean>builder()
                    .code(ResponseCode.UN_ERROR.getCode())
                    .info(ResponseCode.UN_ERROR.getInfo())
                    .data(false)
                    .build();
        }
    }

    /**
     * 删除任务
     *
     * @param taskId
     * @return
     */
    @DeleteMapping("/delete/{taskId}")
    public Response deleteTask(@PathVariable String taskId) {
        try {
            log.info("删除任务: taskId={}", taskId);
            taskService.deleteTaskById(taskId);

            Response<Boolean> response = Response.<Boolean>builder()
                    .code(ResponseCode.SUCCESS.getCode())
                    .info(ResponseCode.SUCCESS.getInfo())
                    .build();
            log.info("删除任务成功: taskId={}", taskId);

            return response;
        } catch (Exception e) {
            log.error("删除任务失败: taskId={} message: {}", taskId, e.getMessage());
            return Response.<Boolean>builder()
                    .code(ResponseCode.UN_ERROR.getCode())
                    .info(ResponseCode.UN_ERROR.getInfo())
                    .build();
        }
    }

    /**
     * 抢单
     *
     * @param taskRushReqDTO
     * @return
     */
    @PostMapping("/rushTask")
    public Response<Boolean> rushTask(@RequestBody TaskRushReqDTO taskRushReqDTO) {
        try {
            log.info("抢单任务 id:{}", taskRushReqDTO.getTaskId());
            TaskEntity taskEntity = taskService.getTaskById(taskRushReqDTO.getTaskId());
            // 校验当前用户是否有权限抢任务
            String userId = BaseContext.getCurrentId();
            // 非平台交易型任务不能抢
            if (TaskTypeVO.COMMON_INFO.getCode().equals(taskEntity.getTaskType())) {
                return Response.<Boolean>builder()
                        .code(ResponseCode.IS_COMMON_TASK.getCode())
                        .info(ResponseCode.IS_COMMON_TASK.getInfo())
                        .data(false)
                        .build();
            }
            // 用户不能抢自己的任务
            if (taskEntity.getCreateUserId().equals(userId)) {
                return Response.<Boolean>builder()
                        .code(ResponseCode.NO_TASK_COUNT_RUSH.getCode())
                        .info("用户不能抢自己的任务！")
                        .data(false)
                        .build();
            }
            // 缓存获取当前用户接单数
            String taskCount = taskService.getUserTaskCount(userId);
            if (Constants.USER_TASK_COUNT_TWO.equals(taskCount)) {
                return Response.<Boolean>builder()
                        .code(ResponseCode.NO_TASK_COUNT_RUSH.getCode())
                        .info(ResponseCode.NO_TASK_COUNT_RUSH.getInfo())
                        .data(false)
                        .build();
            }

            Boolean result = taskService.rushTask(taskEntity);

            if (result) {
                log.info("抢单成功");
                return Response.<Boolean>builder()
                        .code(ResponseCode.SUCCESS.getCode())
                        .info(ResponseCode.SUCCESS.getInfo())
                        .data(true)
                        .build();
            } else {
                log.error("任务库存不足!");
                return Response.<Boolean>builder()
                        .code(ResponseCode.TASK_COUNT_NOT_ENOUGH.getCode())
                        .info(ResponseCode.TASK_COUNT_NOT_ENOUGH.getInfo())
                        .data(false)
                        .build();
            }
        } catch (InvalidDataAccessApiUsageException i) {
            log.error("任务库存不足 {}", i.getMessage());
            return Response.<Boolean>builder()
                    .code(ResponseCode.TASK_COUNT_NOT_ENOUGH.getCode())
                    .info(ResponseCode.TASK_COUNT_NOT_ENOUGH.getInfo())
                    .data(false)
                    .build();
        } catch (Exception e) {
            log.error("抢单失败 {}", e.getMessage());
            return Response.<Boolean>builder()
                    .code(ResponseCode.UN_ERROR.getCode())
                    .info(ResponseCode.UN_ERROR.getInfo())
                    .data(false)
                    .build();
        }
    }

    /**
     * 确认任务完成
     *
     * @param taskRushReqDTO
     * @return
     */
    @PostMapping("/confirmTask")
    public Response<Boolean> confirmTask(@RequestBody TaskRushReqDTO taskRushReqDTO) {
        try {
            log.info("确认完成任务 id:{}", taskRushReqDTO.getTaskId());
            // 校验是否有权限确认完成
            TaskEntity task = taskService.getTaskById(taskRushReqDTO.getTaskId());
            if (!task.getCreateUserId().equals(BaseContext.getCurrentId()) || !TaskStatusVO.RECEIVE.getCode().equals(task.getTaskStatus())) {
                return Response.<Boolean>builder()
                        .code(ResponseCode.NO_AUTHORIZED_HAND_TASK.getCode())
                        .info(ResponseCode.NO_AUTHORIZED_HAND_TASK.getInfo())
                        .data(false)
                        .build();
            }

            taskService.confirmFinishTask(taskRushReqDTO.getTaskId());

            log.info("确认完成成功");
            return Response.<Boolean>builder()
                    .code(ResponseCode.SUCCESS.getCode())
                    .info(ResponseCode.SUCCESS.getInfo())
                    .data(true)
                    .build();
        } catch (Exception e) {
            log.error("确认完成失败 {}", e.getMessage());
            return Response.<Boolean>builder()
                    .code(ResponseCode.UN_ERROR.getCode())
                    .info(ResponseCode.UN_ERROR.getInfo())
                    .data(false)
                    .build();
        }
    }

    /**
     * 取消任务
     *
     * @param taskRushReqDTO
     * @return
     */
    @PostMapping("/cancelTask")
    public Response<Boolean> cancelTask(@RequestBody TaskRushReqDTO taskRushReqDTO) {
        try {
            log.info("取消任务 id:{}", taskRushReqDTO.getTaskId());
            TaskEntity task = taskService.getTaskById(taskRushReqDTO.getTaskId());
            if (task == null) {
                return Response.<Boolean>builder()
                        .code(ResponseCode.ILLEGAL_PARAMETER.getCode())
                        .info("该任务不存在")
                        .data(false)
                        .build();
            }
            // 校验是否有权限取消 创建者 且任务需在 发布 / 接单状态 才能取消
            if (!task.getCreateUserId().equals(BaseContext.getCurrentId()) ||
                    !(TaskStatusVO.RECEIVE.getCode().equals(task.getTaskStatus()) || TaskStatusVO.PUBLISH.getCode().equals(task.getTaskStatus()))) {
                return Response.<Boolean>builder()
                        .code(ResponseCode.NO_AUTHORIZED_HAND_TASK.getCode())
                        .info(ResponseCode.NO_AUTHORIZED_HAND_TASK.getInfo())
                        .data(false)
                        .build();
            }

            taskService.cancelTask(task);

            log.info("取消成功");
            return Response.<Boolean>builder()
                    .code(ResponseCode.SUCCESS.getCode())
                    .info(ResponseCode.SUCCESS.getInfo())
                    .data(true)
                    .build();
        } catch (Exception e) {
            log.error("取消任务失败 {}", e.getMessage());
            return Response.<Boolean>builder()
                    .code(ResponseCode.UN_ERROR.getCode())
                    .info(ResponseCode.UN_ERROR.getInfo())
                    .data(false)
                    .build();
        }
    }


}
